import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import com.sun.nio.sctp.AssociationChangeNotification;
import com.sun.nio.sctp.AbstractNotificationHandler;
import com.sun.nio.sctp.HandlerResult;
import com.sun.nio.sctp.MessageInfo;
import com.sun.nio.sctp.SctpChannel;
import com.sun.nio.sctp.ShutdownNotification;
import static com.sun.nio.sctp.AssociationChangeNotification.AssocChangeEvent.*;

public class SCTPFileClient {
	
    private static final int BUFFER_SIZE = 1024;
    static int SERVER_PORT = 3456;
    
    public static void main(String[] args) throws IOException {
        InetSocketAddress serverAddr = new InetSocketAddress("localhost", 
                                                             SERVER_PORT);
        ByteBuffer buf = ByteBuffer.allocateDirect(BUFFER_SIZE);
        byte[] byteArray = new byte[BUFFER_SIZE];
        
        SctpChannel sc = SctpChannel.open(serverAddr, 0, 0);

        printInfo(sc);

        /* handler to keep track of association setup and termination */
        AssociationHandler assocHandler = new AssociationHandler();

         /* expect two messages and two notifications */
        MessageInfo messageInfo = null;
       
        FileOutputStream out = null;

        out = new FileOutputStream("testout.jpg");
        
        
        int index = 0, offset = 0;
	do {
            messageInfo = sc.receive(buf, System.out, assocHandler);
            buf.flip();
            
            if (buf.limit() > 0 ) {
            	offset = offset + buf.remaining();
            	System.out.println("received " + buf.remaining() + " bytes, total " + offset + " bytes");
            	System.out.println( "buf.limit()=" + buf.limit() + " buf.position()=" + buf.position() + " buf.remaining()=" + buf.remaining() );
            	buf.get( byteArray , 0 , buf.limit());
            	
            	System.out.println( "buf.limit()=" + buf.limit() + " buf.position()=" + buf.position() + " buf.remaining()=" + buf.remaining() );
            	
            	out.write( byteArray, 0, buf.limit() );
            	
            }
            buf.clear();
        } while (messageInfo != null);
	
	out.flush();
	
    out.close();

	sc.close();
	

        
    }

    static class AssociationHandler
        extends AbstractNotificationHandler<PrintStream>
    {
        @Override
        public HandlerResult handleNotification(AssociationChangeNotification not,
                                                PrintStream stream) {
            if (not.event().equals(COMM_UP)) {
                int outbound = not.association().maxOutboundStreams();
                int inbound = not.association().maxInboundStreams();
                stream.printf("New association setup with %d outbound streams" +
                              ", and %d inbound streams.\n", outbound, inbound);
            }

            return HandlerResult.CONTINUE;
        }

        @Override
        public HandlerResult handleNotification(ShutdownNotification not,
                                                PrintStream stream) {
            stream.printf("The association has been shutdown.\n");
            return HandlerResult.RETURN;
        }
    }

    public static void printInfo(SctpChannel sctpChannel)
    {
	   try
	   {
	    System.out.println("sctpChannel.getRemoteAddresses() = " + sctpChannel.getRemoteAddresses());
            System.out.println("sctpChannel.getAllLocalAddresses() = " + sctpChannel.getAllLocalAddresses());
            System.out.println("sctpChannel.isConnectionPending() = " + sctpChannel.isConnectionPending());
            System.out.println("sctpChannel.isOpen() = " + sctpChannel.isOpen());
            System.out.println("sctpChannel.isRegistered() = " + sctpChannel.isRegistered());
            System.out.println("sctpChannel.provider() = " + sctpChannel.provider());
            System.out.println("sctpChannel.association() = " + sctpChannel.association());
	   }
	   catch(IOException e)
	   {
		   e.printStackTrace();
	   }
    }
}
